package com.dy.design_pattern_study.abstract_factory_pattern.dome_abstract_factory.dome_simple_factory;

import com.dy.design_pattern_study.abstract_factory_pattern.dome_abstract_factory.IDB.IDepartment;
import com.dy.design_pattern_study.abstract_factory_pattern.dome_abstract_factory.IDB.IUser;

import java.util.ArrayList;
import java.util.List;

/**
 * @CreateBy zhangdingyi
 * @Date 2023-04-05
 * @Content 利用反射改造简单工厂
 * 现在 简单工厂都不需要 知道是哪个类 直接创建对应的实例
 */
public class BaseDBReflex {

    private static List<String> readXml;
    static {
        readXml = ReadXmlData.readXml();
    }

    public static List<IUser> createUser() {
        List<IUser> results = getResults("User");
        return results;
    }

    public static List<IDepartment> createDepartment() {
        //这里是有一个 自动配置 类型，可以根据上下文来确定具体的类型 -因此这里不用显示的输入类型
        List<IDepartment> results = getResults("Department");
        return results;
    }

    /**
     * 封装 把 读取xml也封装起来一起使用
     * @param db
     * @return
     * @param <T>
     */
    private static <T> List<T> getResults(String db) {
        //字符串的值可以通过xml来配置
        List<T> results = new ArrayList<>();
        for (String url : readXml) {
            if (url.indexOf(db) != -1){
                T t = getObject(url);
                results.add(t);
            }
        }
        return results;
    }

    /**
     * 反射调用类 通用模板
     *
     * @param db
     * @param <T>
     * @return
     */
    private static <T> T getObject(String db) {
        final String factoryLocation = db;
        //选择生产工厂(通过反射创建对象)
        T result = null;
        try {
            //利用类名，来创建类实例
            result = (T) Class.forName(factoryLocation).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
